package cn.ug.pay.service.impl;

import cn.ug.account.bean.DataDictionaryBean;
import cn.ug.activity.bean.CouponMemberBean;
import cn.ug.activity.mq.ContractMQ;
import cn.ug.activity.mq.RewardsMQ;
import cn.ug.bean.base.SerializeObject;
import cn.ug.bean.type.ResultType;
import cn.ug.config.CacheUtilsService;
import cn.ug.config.FundRateConfig;
import cn.ug.config.RedisGlobalLock;
import cn.ug.core.SerializeObjectError;
import cn.ug.core.ensure.Ensure;
import cn.ug.enums.*;
import cn.ug.feign.*;
import cn.ug.mall.bean.GoldBean;
import cn.ug.mall.bean.GoldBeanProvide;
import cn.ug.mall.bean.GoldPrivilegeBean;
import cn.ug.mall.bean.PrivilegeTemplateBean;
import cn.ug.mq.DelayMessagePostProcessor;
import cn.ug.msg.bean.status.CommonConstants;
import cn.ug.msg.bean.type.SmsType;
import cn.ug.msg.mq.Msg;
import cn.ug.msg.mq.Sms;
import cn.ug.msg.mq.WxMessageParamBean;
import cn.ug.msg.mq.WxNotifyData;
import cn.ug.pay.bean.FrozenTbillBean;
import cn.ug.pay.bean.TbillCenterBean;
import cn.ug.pay.bean.TbillRecord;
import cn.ug.pay.bean.WaitingPayBean;
import cn.ug.pay.bean.enumeration.GoldBeanProportionEnum;
import cn.ug.pay.bean.enumeration.TbillTypeEnum;
import cn.ug.pay.bean.response.BankCardFindBean;
import cn.ug.pay.bean.response.UserInvestBean;
import cn.ug.pay.bean.status.TbillStatusEnum;
import cn.ug.pay.bean.type.BillType;
import cn.ug.pay.bean.type.ProductOrderPayStatus;
import cn.ug.pay.bean.type.TbillSourceEnum;
import cn.ug.pay.bean.type.TradeType;
import cn.ug.pay.mapper.*;
import cn.ug.pay.mapper.entity.*;
import cn.ug.pay.service.*;
import cn.ug.product.bean.response.LeaseDay;
import cn.ug.product.bean.response.ProductFindBean;
import cn.ug.product.bean.response.ProductSubtractBean;
import cn.ug.util.BigDecimalUtil;
import cn.ug.util.Common;
import cn.ug.util.SerialNumberWorker;
import cn.ug.util.UF;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

import static cn.ug.config.QueueName.*;
import static cn.ug.util.ConstantUtil.GOLD_WEIGHT_RANGE;
import static cn.ug.util.ConstantUtil.NORMAL_DATE_FORMAT;
import static java.math.BigDecimal.ROUND_HALF_UP;

@Service
public class PayTbillServiceImpl implements PayTbillService {
    private static Log log = LogFactory.getLog(PayTbillServiceImpl.class);
    @Autowired
    private PayTbillMapper payTbillMapper;
    @Autowired
    private ProductService productService;
    @Autowired
    private RedisGlobalLock redisGlobalLock;
    @Autowired
    private FundRateConfig fundRateConfig;
    @Autowired
    private PriceService priceService;
    @Autowired
    private RateSettingsService rateSettingsService;
    @Autowired
    private DataDictionaryService dataDictionaryService;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private PayTbillStatisticsMapper payTbillStatisticsMapper;
    @Autowired
    private PayTbillStatusMapper payTbillStatusMapper;
    @Autowired
    private CouponRepertoryService couponRepertoryService;
    @Autowired
    private PayExperienceOrderMapper payExperienceOrderMapper;
    @Autowired
    private MemberAccountMapper memberAccountMapper;
    @Autowired
    private ExperienceBillMapper experienceBillMapper;
    @Autowired
    private CacheUtilsService cacheUtilsService;
    @Autowired
    private BillMapper billMapper;
    @Autowired
    private PayGoldBeanRecordMapper payGoldBeanRecordMapper;
    @Autowired
    private PayGoldBeanRecordService payGoldBeanRecordService;
    @Autowired
    private PayTbillLeasebackService payTbillLeasebackService;
    @Resource
    private BankCardService bankCardService;
    @Resource
    private BillService billService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void completeOrder(String orderNO) {
        String key = "PayTbillServiceImpl:completeOrder:" + orderNO;
        if (!redisGlobalLock.lock(key)) {
            return;
        }
        try {
            PayExperienceOrder order = payExperienceOrderMapper.findByOrderNO(orderNO);
            if (order == null || order.getStatus() != 1) {
                return;
            }
            if (order.getIncomeType() != 1 && order.getIncomeType() != 2) {
                return;
            }
            MemberAccount memberAccount = memberAccountMapper.findByMemberId(order.getMemberId());
            if (memberAccount == null) {
                return;
            }
            // 1. 更改体验金订单表信息；
            Map<String, Object> leasebackParams = new HashMap<String, Object>();
            leasebackParams.put("status", 2);
            leasebackParams.put("modifyTime", UF.getFormatDateTime(UF.getDateTime()));
            leasebackParams.put("orderNO", order.getOrderNO());
            int rows = payExperienceOrderMapper.update(leasebackParams);
            Ensure.that(rows).isLt(1, "00000005");
            // 2. 奖励发放
            if (order.getIncomeType() == 1) {
                Map<String, Object> accountMap = new HashMap<String, Object>();
                accountMap.put("id", memberAccount.getId());
                accountMap.put("fundAmount", memberAccount.getFundAmount().add(order.getIncomeAmount()));
                accountMap.put("usableAmount", memberAccount.getUsableAmount().add(order.getIncomeAmount()));
                accountMap.put("totalIncomeGram", memberAccount.getTotalIncomeGram().add(order.getIncomeGram()));
                accountMap.put("convertAmount", memberAccount.getConvertAmount().add(order.getIncomeAmount()));
                accountMap.put("convertBean", memberAccount.getConvertBean() + order.getIncomeBean());
                rows = memberAccountMapper.updateByPrimaryKeySelective(accountMap);
                Ensure.that(rows).isLt(1, "00000005");
                // 3. 新增收支记录
                Bill billBean = new Bill();
                billBean.setOrderId(SerialNumberWorker.getInstance().nextId());
                billBean.setMemberId(order.getMemberId());
                billBean.setAmount(order.getIncomeAmount());
                billBean.setFee(BigDecimal.ZERO);
                billBean.setActualAmount(order.getIncomeAmount().subtract(BigDecimal.ZERO));
                billBean.setType(BillType.INCOME.getValue());
                billBean.setId(UF.getRandomUUID());
                billBean.setTradeType(TradeType.EXPERIENCE_LEASEBACK_REWARDS.getValue());
                billBean.setOrderId(SerialNumberWorker.getInstance().nextId());
                rows = billMapper.insert(billBean);
                Ensure.that(rows).isLt(1, "00000005");
            } else if (order.getIncomeType() == 2) {
                Map<String, Object> accountParam = new HashMap<String, Object>();
                accountParam.put("id", memberAccount.getId());
                accountParam.put("freezeBean", memberAccount.getFreezeBean() - order.getIncomeBean());
                accountParam.put("usableBean", memberAccount.getUsableBean() + order.getIncomeBean());
                accountParam.put("totalBean", memberAccount.getFreezeBean() + memberAccount.getUsableBean());
                accountParam.put("totalIncomeGram", memberAccount.getTotalIncomeGram().add(order.getIncomeGram()));
                accountParam.put("convertAmount", memberAccount.getConvertAmount().add(order.getIncomeAmount()));
                accountParam.put("convertBean", memberAccount.getConvertBean() + order.getIncomeBean());
                rows = memberAccountMapper.updateByPrimaryKeySelective(accountParam);
                Ensure.that(rows).isLt(1, "00000005");

                PayGoldBeanRecord beanRecord = new PayGoldBeanRecord();
                beanRecord.setOrderNO(OrderNOPrefixEnum.GB.name() + SerialNumberWorker.getInstance().nextId());
                beanRecord.setType(1);
                beanRecord.setRemark(GoldBeanRemarkEnum.EXPERIENCE_REWARDS.getRemark());
                beanRecord.setGoldBean(order.getIncomeBean());
                beanRecord.setGoldGram(order.getIncomeGram());
                beanRecord.setMemberId(memberAccount.getMemberId());
                beanRecord.setAddTime(UF.getFormatDateTime(LocalDateTime.now()));
                beanRecord.setSuccessTime(UF.getFormatDateTime(LocalDateTime.now()));
                rows = payGoldBeanRecordMapper.insert(beanRecord);
                Ensure.that(rows).isLt(1, "00000005");
            }
            // 4. 消息通知
            Msg msg = new Msg();
            msg.setMemberId(order.getMemberId());
            msg.setType(CommonConstants.MsgType.EXPERIENCE_BECOME_DUE.getIndex());
            Map<String, String> paramMap = new HashMap<>();
            paramMap.put("totalGram", String.valueOf(order.getTotalGram()));
            msg.setParamMap(paramMap);
            //amqpTemplate.convertAndSend(QUEUE_MSG_SEND, msg);
            amqpTemplate.convertAndSend(QUEUE_DELAY_PER_MESSAGE_TTL_MSG_SEND, msg, new DelayMessagePostProcessor(8 * 60 * 60 * 1000));
        } finally {
            redisGlobalLock.unlock(key);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String saveExperienceOrder(String memberId, String productId, int totalGram, BigDecimal goldPrice, String hashKey) {
        SerializeObject<ProductFindBean> obj = productService.queryProductById(productId);
        if (null == obj || obj.getCode() != ResultType.NORMAL || obj.getData() == null) {
            Ensure.that(true).isTrue("17000601");
        }
        ProductFindBean productBean = obj.getData();
        log.info("产品信息：" + JSONObject.toJSONString(productBean));
        if (productBean.getLeaseDayList() == null || productBean.getLeaseDayList().size() == 0) {
            Ensure.that(true).isTrue("00000002");
        }
        if (productBean.getShelfState() == 2) {
            Ensure.that(true).isTrue("17000720");
        }
        if (productBean.getIsOpen() != null && productBean.getIsOpen() == 2) {
            Ensure.that(true).isTrue("170020456");
        }
        if (productBean.getGramMin() != null && productBean.getGramMin().doubleValue() > totalGram) {
            Ensure.that(true).isTrue("170020461", String.valueOf(productBean.getGramMin()));
        }
        Integer canBuyUserType = productBean.getCanBuyUserType();
        canBuyUserType = canBuyUserType == null ? 1 : canBuyUserType;
        if (canBuyUserType == 2) {
            int successfulNum = payTbillMapper.countSuccessfulNum(memberId);
            if (successfulNum == 0) {
                Ensure.that(true).isTrue("17002043");
            }
        } else if (canBuyUserType == 3) {
            int successfulNum = payTbillMapper.countSuccessfulNum(memberId);
            if (successfulNum > 0) {
                Ensure.that(true).isTrue("17002042");
            }
        }
        String key = "PayTbillServiceImpl:saveExperienceOrder:" + memberId + ":" + productId;
        if (!redisGlobalLock.lock(key)) {
            Ensure.that(true).isTrue("17000714");
        }
        try {
            MemberAccount memberAccount = memberAccountMapper.findByMemberId(memberId);
            if (memberAccount == null) {
                Ensure.that(true).isTrue("00000002");
            }
            if (memberAccount.getUsableGram() < totalGram) {
                Ensure.that(true).isTrue("170020460");
            }
            int num = payExperienceOrderMapper.countSuccessfulNum(memberId);
            PayExperienceOrder order = new PayExperienceOrder();
            order.setMemberId(memberId);
            Integer incomeType = productBean.getLeaseCloseType();
            incomeType = incomeType == null ? 1 : incomeType;
            order.setIncomeType(incomeType);
            order.setOrderNO(OrderNOPrefixEnum.PE.name() + SerialNumberWorker.getInstance().nextId());
            order.setAddTime(UF.getFormatDateTime(UF.getDateTime()));
            order.setProductId(productId);
            order.setProductName(productBean.getName());
            order.setTotalGram(totalGram);
            order.setLeasebackDays(productBean.getLeaseDayList().get(0).getLeaseDay());
            order.setYearIncome(productBean.getLeaseDayList().get(0).getYearsIncome());
            order.setGoldPrice(goldPrice);
            LocalDateTime startTime = UF.getDateTime(UF.getFormatDateNow()).plusDays(productBean.getInterestAccrualDay());
            LocalDateTime endTime = startTime.plusDays(order.getLeasebackDays());
            order.setStartTime(UF.getFormatDateTime(startTime));
            order.setEndTime(UF.getFormatDateTime(endTime));
            BigDecimal income = calculateIncomeAmount(new BigDecimal(order.getTotalGram()), order.getLeasebackDays(), order.getYearIncome());
            order.setIncomeGram(income);
            int beans = (int) Math.round(income.multiply(new BigDecimal(GoldBeanProportionEnum.PROPORTION.getValue())).doubleValue());
            order.setIncomeBean(beans);
            order.setIncomeAmount(order.getGoldPrice().multiply(order.getIncomeGram()));
            int rows = payExperienceOrderMapper.insert(order);
            Ensure.that(rows).isLt(1, "00000005");
            if (num == 0) {
                SerializeObject rateBean = rateSettingsService.get(RateKeyEnum.GOLD_BEAN_PROVIDE.getKey());
                if (rateBean != null && rateBean.getData() != null) {
                    GoldBeanProvide goldBeanProvide = JSON.parseObject(JSONObject.toJSONString(rateBean.getData()), GoldBeanProvide.class);
                    if (goldBeanProvide != null && goldBeanProvide.getFirstBuyExperienceGold() != null && goldBeanProvide.getFirstBuyExperienceGold() > 0) {
                        int goldBeans = goldBeanProvide.getFirstBuyExperienceGold();
                        String remark = GoldBeanRemarkEnum.PAY_EXPERIENCE_REWARDS.getRemark();
                        int type = 1;
                        PayGoldBeanRecord beanRecord = new PayGoldBeanRecord();
                        beanRecord.setOrderNO(OrderNOPrefixEnum.GB.name() + SerialNumberWorker.getInstance().nextId());
                        beanRecord.setType(type);
                        beanRecord.setRemark(remark);
                        beanRecord.setGoldBean(goldBeans);
                        beanRecord.setGoldGram(new BigDecimal(goldBeans / 10000.0));
                        beanRecord.setMemberId(memberId);
                        beanRecord.setAddTime(UF.getFormatDateTime(LocalDateTime.now()));
                        beanRecord.setSuccessTime(UF.getFormatDateTime(LocalDateTime.now()));
                        boolean result = payGoldBeanRecordService.save(beanRecord);
                        if (!result) {
                            Ensure.that(0).isLt(1, "00000005");
                        }
                    }
                }
            }
            if (order.getIncomeType() == 2) {
                Map<String, Object> accountParam = new HashMap<String, Object>();
                accountParam.put("id", memberAccount.getId());
                accountParam.put("freezeBean", memberAccount.getFreezeBean() + order.getIncomeBean());
                accountParam.put("totalBean", memberAccount.getFreezeBean() + order.getIncomeBean() + memberAccount.getUsableBean());
                rows = memberAccountMapper.updateByPrimaryKeySelective(accountParam);
                Ensure.that(rows).isLt(1, "00000005");
            }
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("id", memberAccount.getId());
            map.put("usableGram", memberAccount.getUsableGram() - totalGram);
            rows = memberAccountMapper.updateByPrimaryKeySelective(map);
            Ensure.that(rows).isLt(1, "00000005");
            ExperienceBillEntity entity = new ExperienceBillEntity();
            entity.setGram(totalGram);
            entity.setType(2);
            entity.setMemberId(memberId);
            entity.setOrderNo(order.getOrderNO());
            entity.setTradeType(ExperienceTradeTypeEnum.BUY_GOLD.getType());
            entity.setAddTime(UF.getDateTime());
            entity.setModifyTime(UF.getDateTime());
            rows = experienceBillMapper.insert(entity);
            Ensure.that(rows).isLt(1, "00000005");
            RewardsMQ rewardsMQ = new RewardsMQ();
            rewardsMQ.setProductId(order.getProductId());
            rewardsMQ.setScene(3);
            rewardsMQ.setMemberId(order.getMemberId());
            rewardsMQ.setOrderId(order.getOrderNO());
            amqpTemplate.convertAndSend(QUEUE_ACTIVITY_REWARDS, rewardsMQ);

            Msg msg = new Msg();
            msg.setMemberId(memberId);
            msg.setType(CommonConstants.MsgType.PAY_EXPERIENCE.getIndex());
            Map<String, String> paramMap = new HashMap<>();
            paramMap.put("totalGram", String.valueOf(totalGram));
            msg.setParamMap(paramMap);
            amqpTemplate.convertAndSend(QUEUE_MSG_SEND, msg);
            cacheUtilsService.deleteCache(hashKey);
            return order.getOrderNO();
        } finally {
            redisGlobalLock.unlock(key);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveExperienceGram(String memberId, int tradeType, int totalGram) {
        String key = "PayTbillServiceImpl:saveExperienceGram:" + memberId;
        if (!redisGlobalLock.lock(key)) {
            Ensure.that(true).isTrue("17000714");
        }
        try {
            MemberAccount memberAccount = memberAccountMapper.findByMemberId(memberId);
            if (memberAccount == null) {
                Ensure.that(true).isTrue("00000002");
            }
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("id", memberAccount.getId());
            map.put("usableGram", memberAccount.getUsableGram() + totalGram);
            int rows = memberAccountMapper.updateByPrimaryKeySelective(map);
            Ensure.that(rows).isLt(1, "00000005");
            ExperienceBillEntity entity = new ExperienceBillEntity();
            entity.setGram(totalGram);
            entity.setType(1);
            entity.setMemberId(memberId);
            entity.setOrderNo(OrderNOPrefixEnum.PE.name() + SerialNumberWorker.getInstance().nextId());
            entity.setTradeType(tradeType);
            entity.setAddTime(UF.getDateTime());
            entity.setModifyTime(UF.getDateTime());
            rows = experienceBillMapper.insert(entity);
            Ensure.that(rows).isLt(1, "00000005");
            return true;
        } finally {
            redisGlobalLock.unlock(key);
        }
    }

    private BigDecimal calculateIncomeAmount(BigDecimal weight, int investDay, BigDecimal yearsIncome) {
        if (BigDecimalUtil.isZeroOrNull(weight) || investDay < 0 || BigDecimalUtil.isZeroOrNull(yearsIncome)) {
            return BigDecimal.ZERO;
        }
        // 收益计算公式 = 购买克重 * 投资期限 * 年化收益 / 100 / 365
        // *投资期限
        BigDecimal income = weight.multiply(new BigDecimal(investDay));
        // *年化收益/100/365
        income = income.multiply(yearsIncome);
        income = income.divide(new BigDecimal("100"), 10, ROUND_HALF_UP);
        income = income.divide(new BigDecimal("365"), 10, ROUND_HALF_UP);

        return BigDecimalUtil.to5Point(income);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map save(String memberId, String productId, int num, int beans, String couponId, int leaseId, String ticketId) {
        log.info("提单参数：memberId：" + memberId + ", beans=" + beans + "+couponId=" + couponId);
        SerializeObject<ProductFindBean> obj = productService.queryProductById(productId);
        if (null == obj || obj.getCode() != ResultType.NORMAL || obj.getData() == null) {
            Ensure.that(true).isTrue("17000601");
        }
        ProductFindBean productBean = obj.getData();
        //折扣金产品判断是否是否有购买机会
        if (ProductTypeEnum.DISCOUNT_GOLD.getType() == productBean.getType()) {
            SerializeObject<ProductSubtractBean> serializeObject = productService.queryMemberIdSubtractNum(memberId, productId);
            if (null == serializeObject || serializeObject.getCode() != ResultType.NORMAL || serializeObject.getData() == null) {
                Ensure.that(true).isTrue("170020492");
            }
            ProductSubtractBean productSubtractBean = serializeObject.getData();
            if (productSubtractBean.getNum() <= 0) {
                Ensure.that(true).isTrue("170020492");
            }
        }
        Map resultMap = new HashMap();
        //正常状态  银行卡没有达到限额
        resultMap.put("status", 0);
        if (productBean.getSpecification() == null || productBean.getSpecification() < 1 || productBean.getLeaseDayList() == null || productBean.getLeaseDayList().size() == 0) {
            Ensure.that(true).isTrue("00000002");
        }

        if (productBean.getShelfState() == 2) {
            Ensure.that(true).isTrue("17000720");
        }
        if (productBean.getIsOpen() != null && productBean.getIsOpen() == 2) {
            Ensure.that(true).isTrue("170020456");
        }
        Integer canBuyUserType = productBean.getCanBuyUserType();
        canBuyUserType = canBuyUserType == null ? 1 : canBuyUserType;
        int successfulNum = payTbillMapper.countSuccessfulNum(memberId);
        if (canBuyUserType == 2) {
            if (successfulNum == 0) {
                Ensure.that(true).isTrue("17002043");
            }
        } else if (canBuyUserType == 3) {
            if (successfulNum > 0) {
                Ensure.that(true).isTrue("17002042");
            }
        }
        Integer userAstrictStatus = productBean.getUserAstrictStatus();
        userAstrictStatus = userAstrictStatus == null ? 0 : userAstrictStatus;
        if (userAstrictStatus == 1) {
            int gram = payTbillMapper.sumSuccessfulGram(memberId, productId);
            Integer userAstrictNum = productBean.getUserAstrictNum();
            int buyNum = gram / productBean.getSpecification();
            userAstrictNum = userAstrictNum == null ? 0 : userAstrictNum;
            if ((buyNum + num) > userAstrictNum) {
                Ensure.that(true).isTrue("17002044", String.valueOf(userAstrictNum));
            }
        } else if (userAstrictStatus == 2) {
            int gram = payTbillMapper.sumSuccessfulGram(memberId, productId);
            Integer userAstrictGram = productBean.getUserAstrictGram();
            userAstrictGram = userAstrictGram == null ? 0 : userAstrictGram;
            if ((gram + num * productBean.getSpecification()) > userAstrictGram) {
                Ensure.that(true).isTrue("17002045", String.valueOf(userAstrictGram));
            }
        }
        Integer stock = productBean.getStock();
        stock = stock == null ? 0 : stock;
        if (num > stock) {
            Ensure.that(true).isTrue("17002046");
        }

        //金豆判断
        if (beans > 0) {
            SerializeObject rateBean = rateSettingsService.get(RateKeyEnum.GOLD_BEAN.getKey());
            if (rateBean != null && rateBean.getData() != null) {
                GoldBean goldBean = JSON.parseObject(JSONObject.toJSONString(rateBean.getData()), GoldBean.class);
                if (goldBean == null || goldBean.getGoldBeanMin() == null || goldBean.getGoldBeanMax() == null) {
                    Ensure.that(true).isTrue("170020470");
                }
                int goldBeanMin = goldBean.getGoldBeanMin();
                int goldBeanMax = goldBean.getGoldBeanMax();
                if (beans < goldBeanMin) {
                    Ensure.that(true).isTrue("170020471", String.valueOf(goldBeanMin));
                }
                if (beans > goldBeanMax) {
                    Ensure.that(true).isTrue("170020472", String.valueOf(goldBeanMax));
                }

            }
        }

        PayTbill payTbill = new PayTbill();
        payTbill.setProductId(productId);
        payTbill.setMemberId(memberId);
        payTbill.setBeans(beans);
        payTbill.setLeaseId(leaseId);
        payTbill.setBeanGram(new BigDecimal(beans / 10000.0));
        payTbill.setPortion(num);
        payTbill.setOrderNO(OrderNOPrefixEnum.TB.name() + SerialNumberWorker.getInstance().nextId());
        payTbill.setProductName(productBean.getName());
        payTbill.setProcessingFee(BigDecimal.ZERO);
        payTbill.setLockDays(productBean.getLeaseDayList().get(0).getLeaseDay());
        if (1 == productBean.getSettingPriceType()) {
            SerializeObject serializeObject = priceService.currentGoldPrice();
            if (null == serializeObject || serializeObject.getCode() != ResultType.NORMAL) {
                Ensure.that(true).isTrue("17000708");
            }
            BigDecimal goldPrice = new BigDecimal(serializeObject.getData().toString());
            payTbill.setGoldPrice(goldPrice);
        } else {
            payTbill.setGoldPrice(productBean.getSettingPrice());
        }
        if (StringUtils.isNotBlank(couponId) && !StringUtils.equals(couponId, "0")) {
            SerializeObject<CouponMemberBean> couponBean = couponRepertoryService.getMemberCoupon(couponId);
            if (couponBean == null || couponBean.getData() == null || couponBean.getData().getStatus() != 1 || couponBean.getData().getTransactionAmount() > productBean.getSpecification() * num) {
                Ensure.that(true).isTrue("00000005");
            }
            payTbill.setCouponId(couponId);
            payTbill.setCouponGram(new BigDecimal(couponBean.getData().getDiscountAmount()).divide(new BigDecimal("1000"), 5, ROUND_HALF_UP));
        } else {
            payTbill.setCouponGram(BigDecimal.ZERO);
        }
        if (StringUtils.isNotBlank(ticketId) && !StringUtils.equals(ticketId, "0")) {
            SerializeObject<CouponMemberBean> couponBean = couponRepertoryService.getMemberCoupon(ticketId);
            if (couponBean == null || couponBean.getData() == null || couponBean.getData().getStatus() != 1 || couponBean.getData().getTransactionAmount() > productBean.getSpecification() * num) {
                Ensure.that(true).isTrue("00000005");
            }
            payTbill.setTicketId(ticketId);
        }
        payTbill.setTotalGram(productBean.getSpecification() * num);
        if (beans > 0) {
            payTbill.setPayGram(new BigDecimal(payTbill.getTotalGram()).subtract(payTbill.getCouponGram()).subtract(payTbill.getBeanGram()));
        } else {
            payTbill.setPayGram(new BigDecimal(payTbill.getTotalGram()).subtract(payTbill.getCouponGram()));
        }
        BigDecimal itemAmount = payTbill.getGoldPrice().multiply(new BigDecimal(payTbill.getTotalGram()));

        BigDecimal discountAmount = BigDecimal.ZERO;
        int firstAmountType = 1;
        //折扣金不享受其他优惠
        if (ProductTypeEnum.DISCOUNT_GOLD.getType() != productBean.getType()) {
            if (successfulNum == 0 && productBean.getSpecification() * num >= 1) {
                SerializeObject rateBean = rateSettingsService.get(RateKeyEnum.BUY_GOLD_PRIVILEGE.getKey());
                if (rateBean != null && rateBean.getData() != null) {
                    GoldPrivilegeBean bean = JSON.parseObject(JSONObject.toJSONString(rateBean.getData()), GoldPrivilegeBean.class);
                    if (bean != null && bean.getType() == 2) {
                        if (bean.getPrivilegeType() != null && bean.getPrivilegeType() == 1) {
                            firstAmountType = 1;
                        }
                        if (bean.getPrivilegeType() != null && bean.getPrivilegeType() == 2) {
                            firstAmountType = 2;
                        }
                    }
                    log.info("提单首单优惠参数：bean：" + JSON.toJSONString(bean) + ", productBean.getSpecification()*num=" + productBean.getSpecification() * num);
                    discountAmount = fundRateConfig.getFirstAmount(bean, productBean.getSpecification() * num);
                }
            }
            discountAmount = discountAmount == null ? BigDecimal.ZERO : discountAmount;
            if (firstAmountType == 2) {
                discountAmount = new BigDecimal(discountAmount.intValue());
            }
        }
        payTbill.setFirstAmount(discountAmount);
        payTbill.setFirstAmountType(firstAmountType);

        discountAmount = BigDecimal.ZERO;
        int discountAmountType = 1;
        //折扣金不享受其他优惠
        if (ProductTypeEnum.DISCOUNT_GOLD.getType() != productBean.getType()) {
            SerializeObject discountRateBean = rateSettingsService.findONTemplateByType(1);
            if (discountRateBean != null && discountRateBean.getData() != null) {
                PrivilegeTemplateBean bean = JSON.parseObject(JSONObject.toJSONString(discountRateBean.getData()), PrivilegeTemplateBean.class);
                if (bean != null) {
                    if (bean.getWay() != null) {
                        discountAmountType = bean.getWay();
                    }
                }
                if (discountAmountType == 1) {
                    discountAmount = fundRateConfig.getDiscountAmount(bean, new BigDecimal(payTbill.getTotalGram()), 0);
                } else if (discountAmountType == 2) {
                    discountAmount = fundRateConfig.getDiscountAmount(bean, new BigDecimal(payTbill.getTotalGram()), 0);
                } else if (discountAmountType == 3) {
                    discountAmount = new BigDecimal(fundRateConfig.getDiscountAmount(bean, new BigDecimal(payTbill.getTotalGram()), 0).intValue());
                }
            }
        }
        payTbill.setDiscountAmount(discountAmount);
        payTbill.setDiscountAmountType(discountAmountType);
        String key = "PayTbillServiceImpl:save:" + memberId + ":" + productId;
        if (!redisGlobalLock.lock(key)) {
            Ensure.that(true).isTrue("17000714");
        }
        try {
            MemberAccount memberAccount = memberAccountMapper.findByMemberId(memberId);
            if (memberAccount == null) {
                Ensure.that(true).isTrue("00000005");
            }
            if (beans > 0) {
                if (beans > memberAccount.getUsableBean()) {
                    Ensure.that(true).isTrue("170020473");
                }
            }
            BigDecimal discount = payTbill.getGoldPrice().multiply(payTbill.getCouponGram());
            payTbill.setSource(TbillSourceEnum.BUY_GOLD.getValue());
            // 黄金买入手续费 && 现金购买
            BigDecimal fee = BigDecimal.ZERO;
            SerializeObject rateBean = rateSettingsService.get(RateKeyEnum.BUY_GOLD.getKey());
            if (rateBean != null && rateBean.getData() != null) {
                JSONObject json = JSON.parseObject(JSONObject.toJSONString(rateBean.getData()));
                int dayNum = payTbillMapper.getTransactionNumForThisDay(memberId);
                int monthNum = payTbillMapper.getTransactionNumForThisMonth(memberId);
                fee = fundRateConfig.getFee(json, itemAmount, dayNum, monthNum);
            }
            payTbill.setFee(fee);
            payTbill.setTotalAmount(itemAmount);
            BigDecimal goldBeanPrice = BigDecimal.ZERO;
            if (ProductTypeEnum.DISCOUNT_GOLD.getType() != productBean.getType()) {
                // 支付金额（商品总价+手续费-折扣-首单优惠-买金优惠-金豆优惠）
                goldBeanPrice = BigDecimalUtil.to2Point(payTbill.getBeanGram().multiply(payTbill.getGoldPrice()));
            }
            //BigDecimal actualAmount = BigDecimalUtil.add(payTbill.getTotalAmount(), payTbill.getFee()).subtract(discount).subtract(payTbill.getFirstAmount()).subtract(payTbill.getDiscountAmount()).subtract(goldBeanPrice);
            BigDecimal actualAmount = BigDecimalUtil.add(payTbill.getTotalAmount(), payTbill.getFee()).subtract(discount).subtract(goldBeanPrice);
            if (firstAmountType == 1) {
                actualAmount = actualAmount.subtract(payTbill.getFirstAmount());
            }
            if (discountAmountType == 1) {
                actualAmount = actualAmount.subtract(payTbill.getDiscountAmount());
            } else if (discountAmountType == 2) {
                payTbill.setPayGram(payTbill.getPayGram().subtract(payTbill.getDiscountAmount()));
                actualAmount = actualAmount.subtract(BigDecimalUtil.to2Point(payTbill.getDiscountAmount().multiply(payTbill.getGoldPrice())));
            }
            if (ProductTypeEnum.DISCOUNT_GOLD.getType() == productBean.getType()) {
                actualAmount = actualAmount.subtract(productBean.getMarketPrice());
            }
            payTbill.setPayAmount(actualAmount);
            payTbill.setAddTime(UF.getFormatDateTime(UF.getDateTime()));
            payTbill.setModifyTime(UF.getFormatDateTime(UF.getDateTime()));
            SerializeObject resultRate = rateSettingsService.get(RateKeyEnum.UNPAID_TIME.getKey());
            if (resultRate.getData() != null) {
                Map<String, Object> resultRateMap = (Map<String, Object>) resultRate.getData();
                LocalDateTime stopPayTime = UF.getDateTime().plusMinutes((Integer) resultRateMap.get(RateKeyEnum.UNPAID_TIME.getKey()));
                payTbill.setEndTime(UF.getFormatDateTime(stopPayTime));
            }
            //todo 统计银行卡限额
            //余额不足
            if (memberAccount.getUsableAmount().compareTo(payTbill.getPayAmount()) < 0) {
                //差额 即：需要通过银行卡扣除的金额
                BigDecimal balance = payTbill.getPayAmount().subtract(memberAccount.getUsableAmount());
                BankCardFindBean entity = bankCardService.queryMemberBankCard(memberId);
                //单笔限额
                if (balance.compareTo(entity.getAmountOnce()) > 0) {
                    //超过单笔限额提示
                    resultMap.put("status", 1);
                    resultMap.putAll(Common.beanToMap(entity));
                    return resultMap;
                }
                //单月限额
                BigDecimal sumAmount = billService.getTransactionAmountForThisMonth(memberId);
                if (sumAmount == null)
                    sumAmount = new BigDecimal(0);

                if (sumAmount.compareTo(entity.getAmountMonth()) > 0 || (sumAmount.add(balance)).compareTo(entity.getAmountMonth()) > 0) {
                    resultMap.put("status", 2);
                    resultMap.putAll(Common.beanToMap(entity));
                    return resultMap;
                }
            }

            int rows = payTbillMapper.insert(payTbill);
            Ensure.that(rows).isLt(1, "00000005");
            if (StringUtils.isNotBlank(couponId)) {
                couponRepertoryService.lock(couponId);
            }
            if (StringUtils.isNotBlank(ticketId)) {
                couponRepertoryService.lock(ticketId);
            }
            if (ProductTypeEnum.DISCOUNT_GOLD.getType() == productBean.getType()) {
                //锁折扣金的立减次数
                productService.memberSubtractNumUpdate(memberId, productId, 1);
            }
            if (beans > 0) {
                Map<String, Object> accountMap = new HashMap<String, Object>();
                accountMap.put("id", memberAccount.getId());
                accountMap.put("totalBean", memberAccount.getTotalBean() - beans);
                accountMap.put("usableBean", memberAccount.getUsableBean() - beans);
                rows = memberAccountMapper.updateByPrimaryKeySelective(accountMap);
                Ensure.that(rows).isLt(1, "00000005");
            }
            msgByWaitPay(memberId);
            resultMap.put("orderNo", payTbill.getOrderNO());
            return resultMap;
        } finally {
            redisGlobalLock.unlock(key);
        }
    }

    @Override
    public boolean expired() {
        List<PayTbill> bills = payTbillMapper.queryForExpiredList();
        if (bills != null && bills.size() > 0) {
            List<Integer> ids = new ArrayList<Integer>();
            for (PayTbill payTbill : bills) {
                ids.add(payTbill.getId());
                if (StringUtils.isNotBlank(payTbill.getCouponId())) {
                    couponRepertoryService.unlock(payTbill.getCouponId());
                }
                if (StringUtils.isNotBlank(payTbill.getTicketId())) {
                    couponRepertoryService.unlock(payTbill.getTicketId());
                }

                if (ProductTypeEnum.DISCOUNT_GOLD.getType() == payTbill.getProductType()) {
                    //锁折扣金的立减次数解锁
                    productService.memberSubtractNumUpdate(payTbill.getMemberId(), payTbill.getProductId(), 2);
                }

                if (payTbill != null && payTbill.getBeans() > 0) {
                    MemberAccount memberAccount = memberAccountMapper.findByMemberId(payTbill.getMemberId());
                    if (memberAccount != null) {
                        Map<String, Object> accountMap = new HashMap<String, Object>();
                        accountMap.put("id", memberAccount.getId());
                        accountMap.put("totalBean", memberAccount.getTotalBean() + payTbill.getBeans());
                        accountMap.put("usableBean", memberAccount.getUsableBean() + payTbill.getBeans());
                        memberAccountMapper.updateByPrimaryKeySelective(accountMap);
                    }
                }
            }
            return payTbillMapper.expired(ids) > 0 ? true : false;
        }
        return false;
    }

    @Override
    public PayTbill selectByOrderNO(String orderNO) {
        if (StringUtils.isNotBlank(orderNO)) {
            PayTbill payTbill = payTbillMapper.selectByOrderNO(orderNO);
            if (payTbill != null) {
                SerializeObject resultRate = rateSettingsService.get(RateKeyEnum.UNPAID_TIME.getKey());
                if (resultRate.getData() != null) {
                    Map<String, Object> resultRateMap = (Map<String, Object>) resultRate.getData();
                    payTbill.setUnpaidTimeMinute((Integer) resultRateMap.get(RateKeyEnum.UNPAID_TIME.getKey()));
                }
                SerializeObject<ProductFindBean> obj = productService.queryProductById(payTbill.getProductId());
                if (null == obj || obj.getCode() != ResultType.NORMAL) {
                    Ensure.that(true).isTrue("17000601");
                }
                ProductFindBean productBean = obj.getData();
                if (productBean != null && productBean.getLeaseCloseType() != null) {
                    payTbill.setIncomeType(productBean.getLeaseCloseType());
                }
            }
            return payTbill;
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void completePay(String orderNO) {
        log.info("支付成功......");
        String key = "PayTbillServiceImpl:completePay:" + orderNO;
        if (!redisGlobalLock.lock(key)) {
            Ensure.that(true).isTrue("17000714");
        }
        try {
            PayTbill payTbill = payTbillMapper.selectByOrderNO(orderNO);
            if (payTbill.getStatus() == TbillStatusEnum.PAY_SUCCESS.getStatus()) {
                Ensure.that(true).isTrue("17000705");
            }
            SerializeObject<ProductFindBean> obj = productService.queryProductById(payTbill.getProductId());
            if (null == obj || obj.getCode() != ResultType.NORMAL) {
                Ensure.that(true).isTrue("17000601");
            }
            int num = payTbillMapper.countSuccessfulNum(payTbill.getMemberId());
            ProductFindBean productBean = obj.getData();
            Map<String, Object> param = new HashMap<String, Object>();
            param.put("orderNO", orderNO);
            param.put("status", TbillStatusEnum.PAY_SUCCESS.getStatus());
            param.put("successTime", UF.getFormatDateTime(UF.getDateTime()));
            param.put("modifyTime", UF.getFormatDateTime(UF.getDateTime()));
            param.put("readed", 0);
            int rows = payTbillMapper.update(param);
            Ensure.that(rows).isLt(1, "00000005");
            // 首次实物金购买成功赠送金豆
            if (num == 0) {
                SerializeObject rateBean = rateSettingsService.get(RateKeyEnum.GOLD_BEAN_PROVIDE.getKey());
                if (rateBean != null && rateBean.getData() != null) {
                    GoldBeanProvide goldBeanProvide = JSON.parseObject(JSONObject.toJSONString(rateBean.getData()), GoldBeanProvide.class);
                    if (goldBeanProvide != null && goldBeanProvide.getFirstBuyEntityGold() != null && goldBeanProvide.getFirstBuyEntityGold() > 0) {
                        int beans = goldBeanProvide.getFirstBuyEntityGold();
                        String remark = GoldBeanRemarkEnum.PAY_GOLD_REWARDS.getRemark();
                        int type = 1;
                        PayGoldBeanRecord beanRecord = new PayGoldBeanRecord();
                        beanRecord.setOrderNO(OrderNOPrefixEnum.GB.name() + SerialNumberWorker.getInstance().nextId());
                        beanRecord.setType(type);
                        beanRecord.setRemark(remark);
                        beanRecord.setGoldBean(beans);
                        beanRecord.setGoldGram(new BigDecimal(beans / 10000.0));
                        beanRecord.setMemberId(payTbill.getMemberId());
                        beanRecord.setAddTime(UF.getFormatDateTime(LocalDateTime.now()));
                        beanRecord.setSuccessTime(UF.getFormatDateTime(LocalDateTime.now()));
                        payGoldBeanRecordService.save(beanRecord);
                    }
                }
            }
            if (payTbill.getFirstAmountType() == 2) {
                int beans = payTbill.getFirstAmount().intValue();
                String remark = GoldBeanRemarkEnum.FIRST_PAY_REWEARDS.getRemark();
                int type = 1;
                PayGoldBeanRecord beanRecord = new PayGoldBeanRecord();
                beanRecord.setOrderNO(OrderNOPrefixEnum.GB.name() + SerialNumberWorker.getInstance().nextId());
                beanRecord.setType(type);
                beanRecord.setRemark(remark);
                beanRecord.setGoldBean(beans);
                beanRecord.setGoldGram(new BigDecimal(beans / 10000.0));
                beanRecord.setMemberId(payTbill.getMemberId());
                beanRecord.setAddTime(UF.getFormatDateTime(LocalDateTime.now()));
                beanRecord.setSuccessTime(UF.getFormatDateTime(LocalDateTime.now()));
                payGoldBeanRecordService.save(beanRecord);
            }
            if (payTbill.getDiscountAmountType() == 3) {
                int beans = payTbill.getDiscountAmount().intValue();
                String remark = GoldBeanRemarkEnum.EVERY_PAY_GOLD_REWARDS.getRemark();
                int type = 1;
                PayGoldBeanRecord beanRecord = new PayGoldBeanRecord();
                beanRecord.setOrderNO(OrderNOPrefixEnum.GB.name() + SerialNumberWorker.getInstance().nextId());
                beanRecord.setType(type);
                beanRecord.setRemark(remark);
                beanRecord.setGoldBean(beans);
                beanRecord.setGoldGram(new BigDecimal(beans / 10000.0));
                beanRecord.setMemberId(payTbill.getMemberId());
                beanRecord.setAddTime(UF.getFormatDateTime(LocalDateTime.now()));
                beanRecord.setSuccessTime(UF.getFormatDateTime(LocalDateTime.now()));
                payGoldBeanRecordService.save(beanRecord);
            }
            PayTbillStatistics payTbillStatistics = payTbillStatisticsMapper.selectByMemberId(payTbill.getMemberId());
            if (payTbillStatistics == null) {
                payTbillStatistics = new PayTbillStatistics();
                payTbillStatistics.setAddTime(UF.getFormatDateTime(UF.getDateTime()));
                payTbillStatistics.setMemberId(payTbill.getMemberId());
                payTbillStatistics.setTotalBills(1);
                payTbillStatistics.setTotalGram(payTbill.getTotalGram());
                payTbillStatistics.setPendingBills(1);
                payTbillStatistics.setPendingGram(payTbill.getTotalGram());
                rows = payTbillStatisticsMapper.insert(payTbillStatistics);
                Ensure.that(rows).isLt(1, "00000005");
            } else {
                Map<String, Object> staParam = new HashMap<String, Object>();
                staParam.put("memberId", payTbill.getMemberId());
                staParam.put("totalBills", payTbillStatistics.getTotalBills() + 1);
                staParam.put("totalGram", payTbillStatistics.getTotalGram() + payTbill.getTotalGram());
                staParam.put("pendingBills", payTbillStatistics.getPendingBills() + 1);
                staParam.put("pendingGram", payTbillStatistics.getPendingGram() + payTbill.getTotalGram());
                rows = payTbillStatisticsMapper.update(staParam);
                Ensure.that(rows).isLt(1, "00000005");
            }
            log.info("提单订单信息：" + JSONObject.toJSONString(payTbill));
            if (StringUtils.isNotBlank(payTbill.getCouponId())) {
                SerializeObject usedResult = couponRepertoryService.consumeCoupon(payTbill.getCouponId(), payTbill.getGoldPrice().multiply(payTbill.getCouponGram()), payTbill.getOrderNO());
                log.info("优惠券使用结果：" + JSONObject.toJSONString(usedResult));
                /*if (usedResult == null || usedResult.getCode() != ResultType.NORMAL) {
                    Ensure.that(0).isLt(1, "00000005");
                }*/
            }
            if (payTbill.getBeans() > 0) {
                PayGoldBeanRecord beanRecord = new PayGoldBeanRecord();
                beanRecord.setOrderNO(OrderNOPrefixEnum.GB.name() + SerialNumberWorker.getInstance().nextId());
                beanRecord.setType(2);
                beanRecord.setRemark(GoldBeanRemarkEnum.PAY_GOLD_DEDUCTION.getRemark());
                beanRecord.setGoldBean(payTbill.getBeans());
                beanRecord.setGoldGram(payTbill.getBeanGram());
                beanRecord.setMemberId(payTbill.getMemberId());
                beanRecord.setAddTime(UF.getFormatDateTime(LocalDateTime.now()));
                beanRecord.setSuccessTime(UF.getFormatDateTime(LocalDateTime.now()));
                rows = payGoldBeanRecordMapper.insert(beanRecord);
                Ensure.that(rows).isLt(1, "00000005");
            }
            PayTbillStatus payTbillStatus = new PayTbillStatus();
            payTbillStatus.setTbillNO(orderNO);
            payTbillStatus.setOrderNO(SerialNumberWorker.getInstance().nextId());
            payTbillStatus.setAddTime(UF.getFormatDateTime(UF.getDateTime()));
            payTbillStatus.setType(TbillTypeEnum.BUY.getValue());
            payTbillStatus.setStatus(TbillStatusEnum.PAY_SUCCESS.getStatus());
            payTbillStatus.setRemark("");
            payTbillStatus.setModifyTime(UF.getFormatDateTime(UF.getDateTime()));
            payTbillStatusMapper.insert(payTbillStatus);
            productService.addToRaiseGram(productBean.getId(), new BigDecimal(payTbill.getTotalGram()));
            if (productBean.getRaiseGram().doubleValue() > 0) {
                double lowestQuota = 0.0;
                SerializeObject<List<DataDictionaryBean>> beans = dataDictionaryService.findListByClassification(GOLD_WEIGHT_RANGE, 1);
                if (beans != null && beans.getData() != null && beans.getData().size() == 2) {
                    double value0 = Double.parseDouble(beans.getData().get(0).getItemValue());
                    double value1 = Double.parseDouble(beans.getData().get(1).getItemValue());
                    if (value0 > value1) {
                        lowestQuota = productBean.getRaiseGram().doubleValue() * value1 / 100;
                    } else {
                        lowestQuota = productBean.getRaiseGram().doubleValue() * value0 / 100;
                    }
                }
                double hadRaisedGram = productBean.getToRaiseGram().doubleValue() + payTbill.getTotalGram();
                if (lowestQuota > 0 && hadRaisedGram >= lowestQuota) {
                    productService.updateShelfState(productBean.getId(), 2);
                    SerializeObject<List<DataDictionaryBean>> dictionaryBean = dataDictionaryService.findListByClassification(cn.ug.msg.bean.status.CommonConstants.MsgType.PRODUCT_DOWN_SHELF.getName(), 1);
                    if (dictionaryBean != null && dictionaryBean.getData() != null) {
                        List<DataDictionaryBean> data = dictionaryBean.getData();
                        if (data != null && data.size() > 0) {
                            for (DataDictionaryBean bean : data) {
                                Sms sms = new Sms();
                                sms.setPhone(bean.getItemValue());
                                sms.setType(SmsType.SOLD_OUT);
                                Map<String, String> paramMap = new HashMap<>(2);
                                paramMap.put("produtName", productBean.getName());
                                paramMap.put("hour", String.valueOf(Calendar.getInstance().get(Calendar.HOUR_OF_DAY)));
                                sms.setParamMap(paramMap);
                                amqpTemplate.convertAndSend(QUEUE_MSG_SMS_SEND, sms);
                            }
                        }
                    }
                }
            }
            //回租期限
            int investDay = 0;
            //回租开始时间
            String lbstartTime = null;
            //回租结束时间
            String lbendTime = null;
            //预计收益克重
            BigDecimal incomeGram = BigDecimal.ZERO;
            if (payTbill.getLeaseId() > 0) {
                Integer leaseCalculateGoldType = productBean.getLeaseCalculateGoldType();
                leaseCalculateGoldType = leaseCalculateGoldType == null ? 1 : leaseCalculateGoldType;
                String point = "";
                if (leaseCalculateGoldType == 1) {
                    point = "02:30";
                } else {
                    point = productBean.getLeaseCalculateGoldTime();
                }
                SimpleDateFormat format = new SimpleDateFormat(NORMAL_DATE_FORMAT);
                Calendar calendar = Calendar.getInstance();
                calendar.add(Calendar.DAY_OF_YEAR, -1);
                String someday = format.format(calendar.getTime()) + " " + point;
                SerializeObject<Double> result = priceService.getSomedayPrice(someday);
                if (result != null) {
                    double price = result.getData();
                    List<LeaseDay> leaseDayList = productBean.getLeaseDayList();
                    LeaseDay readlLeaseDay = null;
                    for (LeaseDay leaseDay : leaseDayList) {
                        if (leaseDay.getId() == payTbill.getLeaseId()) {
                            readlLeaseDay = leaseDay;
                            break;
                        }
                    }
                    if (readlLeaseDay == null) {
                        Ensure.that(0).isLt(1, "00000002");
                    }
                    investDay = readlLeaseDay.getLeaseDay();
                    BigDecimal income = calculateIncomeAmount(new BigDecimal(payTbill.getTotalGram()), readlLeaseDay.getLeaseDay(), readlLeaseDay.getYearsIncome());
                    incomeGram = income;
                    PayTbillLeaseback payTbillLeaseback = new PayTbillLeaseback();
                    payTbillLeaseback.setTbillNO(orderNO);
                    Integer incomeType = productBean.getLeaseCloseType();
                    incomeType = incomeType == null ? 1 : incomeType;
                    payTbillLeaseback.setIncomeType(incomeType);
                    payTbillLeaseback.setOrderNO(OrderNOPrefixEnum.LB.name() + SerialNumberWorker.getInstance().nextId());

                    LocalDateTime startTime = UF.getDateTime(UF.getFormatDateNow()).plusDays(productBean.getInterestAccrualDay());
                    LocalDateTime endTime = startTime.plusDays(readlLeaseDay.getLeaseDay());
                    payTbillLeaseback.setStartTime(UF.getFormatDateTime(UF.getDateTime()));
                    payTbillLeaseback.setEndTime(UF.getFormatDateTime(endTime));
                    lbstartTime = UF.getFormatDateTime(UF.getDateTime());
                    lbendTime = UF.getFormatDateTime(endTime);
                    payTbillLeaseback.setGoldPrice(new BigDecimal(price));
                    payTbillLeaseback.setLeasebackDays(readlLeaseDay.getLeaseDay());
                    payTbillLeaseback.setYearIncome(readlLeaseDay.getYearsIncome());
                    payTbillLeaseback.setIncomeGram(income);
                    int beans = (int) Math.round(income.multiply(new BigDecimal(GoldBeanProportionEnum.PROPORTION.getValue())).doubleValue());
                    payTbillLeaseback.setIncomeBeans(beans);
                    payTbillLeaseback.setIncomeAmount(BigDecimalUtil.to2Point(income.multiply(new BigDecimal(price))));
                    //金生金奖励 = 原回租奖励   现在回租奖励 = 金生金奖励+黄金红包奖励
                    payTbillLeaseback.setGoldGiveGoldAmount(payTbillLeaseback.getIncomeAmount());
                    if (StringUtils.isNotBlank(payTbill.getTicketId()) && !StringUtils.equals(payTbill.getTicketId(), "0")) {
                        SerializeObject<CouponMemberBean> couponBean = couponRepertoryService.getMemberCoupon(payTbill.getTicketId());
                        if (couponBean == null || couponBean.getData() == null) {
                            Ensure.that(0).isLt(1, "00000005");
                        }
                        payTbillLeaseback.setCouponId(payTbill.getTicketId());
                        //LocalDateTime actualTime = endTime.plusDays(-couponBean.getData().getDiscountAmount());
                        payTbillLeaseback.setActualTime(payTbillLeaseback.getEndTime());
                        //红包卷类型 0黄金红包 1回租卷  2.商城卷
                        payTbillLeaseback.setCouponType(couponBean.getData().getType());
                        //黄金红包奖励
                        payTbillLeaseback.setCouponAwardAmount(BigDecimalUtil.to2Point(new BigDecimal(couponBean.getData().getDiscountAmount()).divide(new BigDecimal(1000)).multiply(new BigDecimal(price))));
                        //折算金额=黄金红包奖励
                        payTbillLeaseback.setCouponAmount(couponBean.getData().getDiscountAmount());
                        //回租收益（元） 40 回租金生金奖励 + 黄金红包奖励
                        payTbillLeaseback.setIncomeAmount(payTbillLeaseback.getIncomeAmount().add(payTbillLeaseback.getCouponAwardAmount()));

                        //todo 回租福利卷换成了黄金红包卷就没有了这个福利券对应年化  切换成金生金加息年化
                        //BigDecimal couponYearIncome = BigDecimalUtil.to2Point(payTbillLeaseback.getYearIncome().multiply(new BigDecimal(payTbillLeaseback.getLeasebackDays()*1.0/(payTbillLeaseback.getLeasebackDays() - couponBean.getData().getDiscountAmount()) - 1)));
                        payTbillLeaseback.setCouponYearIncome(couponBean.getData().getRaiseYearIncome());
                    } else {
                        payTbillLeaseback.setCouponId("");
                        payTbillLeaseback.setActualTime(UF.getFormatDateTime(endTime));
                        payTbillLeaseback.setCouponYearIncome(BigDecimal.ZERO);
                        payTbillLeaseback.setCouponAmount(0);
                    }
                    BigDecimal discountAmount = BigDecimal.ZERO;
                    SerializeObject discountRateBean = rateSettingsService.findONTemplateByType(2);
                    int discountAmountType = 1;
                    if (discountRateBean != null && discountRateBean.getData() != null) {
                        PrivilegeTemplateBean bean = JSON.parseObject(JSONObject.toJSONString(discountRateBean.getData()), PrivilegeTemplateBean.class);
                        if (bean != null && bean.getWay() != null) {
                            discountAmountType = bean.getWay();
                        }
                        discountAmount = fundRateConfig.getDiscountAmount(bean, new BigDecimal(payTbillLeaseback.getLeasebackDays()), 1);
                    }
                    if (discountAmountType == 3) {
                        discountAmount = new BigDecimal(discountAmount.intValue());
                    }
                    payTbillLeaseback.setDiscountAmount(discountAmount);
                    payTbillLeaseback.setDiscountAmountType(discountAmountType);
                    if (!payTbillLeasebackService.save(payTbillLeaseback)) {
                        Ensure.that(0).isLt(1, "00000005");
                    }
                } else {
                    Ensure.that(0).isLt(1, "00000005");
                }
            }

            //触发支付成功的消息
            Msg msg = new Msg();
            msg.setMemberId(payTbill.getMemberId());
            Map<String, String> paramMap = new HashMap<>();
            paramMap.put("productName", payTbill.getProductName());
            paramMap.put("changeGram", String.valueOf(payTbill.getTotalGram()));
            msg.setType(CommonConstants.MsgType.BUY_CURRENT_GOLD.getIndex());
            paramMap.put("gram", String.valueOf(payTbillStatistics.getPendingGram() + payTbill.getTotalGram()));
            msg.setParamMap(paramMap);

            amqpTemplate.convertAndSend(QUEUE_MSG_SEND, msg);

            WxMessageParamBean wxMessageParamBean = new WxMessageParamBean();
            wxMessageParamBean.setMemberId(payTbill.getMemberId());
            wxMessageParamBean.setType(WxTemplateEnum.TBILL_PAY_SUCCESS.getType());
            WxTemplateEnum wxTemplateEnum = WxTemplateEnum.getWxTemplateByCode(WxTemplateEnum.TBILL_PAY_SUCCESS.getType());
            WxNotifyData wxNotifyData = new WxNotifyData();

            Map<String, WxNotifyData.TemplateDataAttr> wxParamMap = new HashMap();
            WxNotifyData.TemplateDataAttr first = new WxNotifyData.TemplateDataAttr();
            first.setDataValue(wxTemplateEnum.getFirstData().replace("{orderNO}", payTbill.getOrderNO()).
                    replace("{couponInfo}", ""));
            wxParamMap.put("first", first);

            WxNotifyData.TemplateDataAttr keyword1 = new WxNotifyData.TemplateDataAttr();
            keyword1.setDataValue(payTbill.getOrderNO());
            wxParamMap.put("keyword1", keyword1);

            WxNotifyData.TemplateDataAttr keyword2 = new WxNotifyData.TemplateDataAttr();
            keyword2.setDataValue(String.valueOf(payTbill.getTotalGram()));
            wxParamMap.put("keyword2", keyword2);

            WxNotifyData.TemplateDataAttr keyword3 = new WxNotifyData.TemplateDataAttr();
            keyword3.setDataValue(BigDecimalUtil.to2Point(payTbill.getPayAmount()).toString());
            wxParamMap.put("keyword3", keyword3);

            WxNotifyData.TemplateDataAttr keyword4 = new WxNotifyData.TemplateDataAttr();
            keyword4.setDataValue(BigDecimalUtil.to2Point(payTbill.getGoldPrice()).toString());
            wxParamMap.put("keyword4", keyword4);

            WxNotifyData.TemplateDataAttr keyword5 = new WxNotifyData.TemplateDataAttr();
            keyword5.setDataValue(UF.getFormatDateTime(UF.getDateTime()));
            wxParamMap.put("keyword5", keyword5);

            WxNotifyData.TemplateDataAttr remark = new WxNotifyData.TemplateDataAttr();
            remark.setDataValue(wxTemplateEnum.getRemark());
            wxParamMap.put("remark", remark);

            wxNotifyData.setData(wxParamMap);
            wxMessageParamBean.setTemplateData(wxNotifyData);
            amqpTemplate.convertAndSend(QUEUE_MSG_WX_SEND, wxMessageParamBean);

            // 生成e签宝合同
            esignAfterCompletePay(payTbill, productBean.getIsActivity(), productBean.getType(), productBean.getSpecification(), investDay, lbstartTime, lbendTime, incomeGram);

            RewardsMQ rewardsMQ = new RewardsMQ();
            rewardsMQ.setProductId(payTbill.getProductId());
            rewardsMQ.setScene(2);
            rewardsMQ.setMemberId(payTbill.getMemberId());
            rewardsMQ.setOrderId(payTbill.getOrderNO());
            rewardsMQ.setAmount(new BigDecimal(payTbill.getTotalGram()));
            rewardsMQ.setPayTotalAmount(payTbill.getTotalAmount());

            amqpTemplate.convertAndSend(QUEUE_ACTIVITY_REWARDS, rewardsMQ);
        } finally {
            redisGlobalLock.unlock(key);
        }
    }
//  //回租期限
//            int investDay = 0;
//            //回租开始时间
//            String lbstartTime = null;
//            //回租结束时间
//            String lbendTime = null;

    /**
     * @param payTbill
     * @param isActivity    是否是活动产品
     * @param type          产品类型
     * @param specification 规格
     * @param investDay     投资周期
     * @param lbStartTime   回租开始时间
     * @param lbEndTime     回租结束时间
     * @param incomeGram    预计回租收益
     */
    public void esignAfterCompletePay(PayTbill payTbill, int isActivity, int type, int specification, int investDay, String lbStartTime, String lbEndTime, BigDecimal incomeGram) {
        ContractMQ contractMQ = new ContractMQ();
        contractMQ.setMemberId(payTbill.getMemberId());
        contractMQ.setOrderNO(payTbill.getOrderNO());
        contractMQ.setPrice(payTbill.getGoldPrice());
        contractMQ.setProductType(type);
        contractMQ.setSpecification(specification);
        contractMQ.setProductId(payTbill.getProductId());
        contractMQ.setProductName(payTbill.getProductName());
        contractMQ.setTradeAmount(payTbill.getPayAmount());
        contractMQ.setIsActivity(isActivity);
        contractMQ.setTradeDate(UF.getFormatDate(UF.getDateTime()));
        contractMQ.setWeight(new BigDecimal(payTbill.getTotalGram()));
        contractMQ.setInvestDay(investDay);
        if (StringUtils.isNotBlank(lbStartTime) && StringUtils.isNotBlank(lbEndTime)) {
            contractMQ.setLbStartTime(lbStartTime);
            contractMQ.setLbEndTime(lbEndTime);
        }
        contractMQ.setIncomeGram(incomeGram);
        amqpTemplate.convertAndSend(QUEUE_ESIGN_CONTRACT, contractMQ);
    }

    @Override
    public List<TbillCenterBean> queryForTbillCenter(String memberId, int status, int offset, int size) {
        if (StringUtils.isNotBlank(memberId)) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("memberId", memberId);
            params.put("status", status);
            params.put("offset", offset);
            params.put("size", size);
            return payTbillMapper.queryForTbillCenter(params);
        }
        return null;
    }


    @Override
    public List<Map<String, Object>> queryForTbillList(String orderNo) {
        String memberId = payTbillMapper.queryForType(OrderNOPrefixEnum.switchString(orderNo));
        if (StringUtils.isNotBlank(memberId)) {
            List<TbillCenterBean> tbillCenterBeanList = payTbillMapper.queryForTbillList(memberId);
            if (!CollectionUtils.isEmpty(tbillCenterBeanList)) {
                List<Map<String, Object>> productFindBeans = new ArrayList<>();
                for (TbillCenterBean tbillCenterBean : tbillCenterBeanList) {
                    SerializeObject<ProductFindBean> obj = productService.queryProductById(tbillCenterBean.getProductId());
                    if (null == obj || obj.getCode() != ResultType.NORMAL || obj.getData() == null) {
                        Ensure.that(true).isTrue("17000601");
                    }
                    ProductFindBean productBean = obj.getData();
                    if (productBean.getLeaseDayList() == null || productBean.getLeaseDayList().size() == 0) {
                        Ensure.that(true).isTrue("00000002");
                    }
                    Map<String, Object> resultMap = new HashMap<>();
                    resultMap.put("name", productBean.getName());
                    resultMap.put("subhead", productBean.getSubhead());
                    resultMap.put("img", productBean.getImg());
                    productFindBeans.add(resultMap);
                }
                return productFindBeans;
            }
        }
        return null;
    }

    @Override
    public int countForTbillCenter(String memberId, int status) {
        if (StringUtils.isNotBlank(memberId)) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("memberId", memberId);
            params.put("status", status);
            return payTbillMapper.countForTbillCenter(params);
        }
        return 0;
    }

    @Override
    public boolean read(String orderNO) {
        if (StringUtils.isNotBlank(orderNO)) {
            return payTbillMapper.read(orderNO) > 0 ? true : false;
        }
        return false;
    }

    @Override
    public boolean readUndeterminedBills(String memberId) {
        if (StringUtils.isNotBlank(memberId)) {
            return payTbillMapper.readUndeterminedBills(memberId) > 0 ? true : false;
        }
        return false;
    }

    @Override
    public int countUnreadNum(String memberId, int status) {
        if (StringUtils.isNotBlank(memberId)) {
            return payTbillMapper.countUnreadNum(memberId, status);
        }
        return 0;
    }

    @Override
    public List<WaitingPayBean> queryForWaitingTbills(String memberId, int offset, int size) {
        if (StringUtils.isNotBlank(memberId)) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("memberId", memberId);
            params.put("offset", offset);
            params.put("size", size);
            return payTbillMapper.queryForWaitingTbills(params);
        }
        return null;
    }

    @Override
    public int countForWaitingTbills(String memberId) {
        if (StringUtils.isNotBlank(memberId)) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("memberId", memberId);
            return payTbillMapper.countForWaitingTbills(params);
        }
        return 0;
    }

    @Override
    public List<TbillRecord> queryForRecords(String productId, int offset, int size) {
        if (StringUtils.isNotBlank(productId)) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("productId", productId);
            params.put("offset", offset);
            params.put("size", size);
            return payTbillMapper.queryForRecords(params);
        }
        return null;
    }

    @Override
    public int countForRecords(String productId) {
        if (StringUtils.isNotBlank(productId)) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("productId", productId);
            return payTbillMapper.countForRecords(params);
        }
        return 0;
    }

    @Override
    public List<PayExperienceOrder> query(String mobile, String name, String memberId, int status, String startAddTime, String endAddTime,
                                          String startOverTime, String endOverTime, String order, String sort, int offset, int size) {
        List<String> orders = Arrays.asList("start_time", "end_time", "add_time", "modify_time");
        Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(mobile)) {
            params.put("mobile", mobile);
        }
        if (StringUtils.isNotBlank(name)) {
            params.put("name", name);
        }
        if (StringUtils.isNotBlank(memberId)) {
            params.put("memberId", memberId);
        }
        params.put("status", status);
        if (StringUtils.isNotBlank(startAddTime)) {
            params.put("startAddTime", startAddTime);
        }
        if (StringUtils.isNotBlank(endAddTime)) {
            params.put("endAddTime", endAddTime);
        }
        if (StringUtils.isNotBlank(startOverTime)) {
            params.put("startOverTime", startOverTime);
        }
        if (StringUtils.isNotBlank(endOverTime)) {
            params.put("endOverTime", endOverTime);
        }
        if (orders.contains(order)) {
            params.put("order", order);
            params.put("sort", "desc");
            if (StringUtils.equalsIgnoreCase(sort, "asc") || StringUtils.equalsIgnoreCase(sort, "desc")) {
                params.put("sort", sort);
            }
        }
        params.put("offset", offset);
        params.put("size", size);
        return payExperienceOrderMapper.query(params);
    }

    @Override
    public int count(String mobile, String name, String memberId, int status, String startAddTime, String endAddTime, String startOverTime, String endOverTime) {
        Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(mobile)) {
            params.put("mobile", mobile);
        }
        if (StringUtils.isNotBlank(name)) {
            params.put("name", name);
        }
        if (StringUtils.isNotBlank(memberId)) {
            params.put("memberId", memberId);
        }
        params.put("status", status);
        if (StringUtils.isNotBlank(startAddTime)) {
            params.put("startAddTime", startAddTime);
        }
        if (StringUtils.isNotBlank(endAddTime)) {
            params.put("endAddTime", endAddTime);
        }
        if (StringUtils.isNotBlank(startOverTime)) {
            params.put("startOverTime", startOverTime);
        }
        if (StringUtils.isNotBlank(endOverTime)) {
            params.put("endOverTime", endOverTime);
        }
        return payExperienceOrderMapper.count(params);
    }

    @Override
    public PayExperienceOrder findByOrderNO(String orderNO) {
        if (StringUtils.isNotBlank(orderNO)) {
            return payExperienceOrderMapper.findByOrderNO(orderNO);
        }
        return null;
    }

    @Override
    public List<PayExperienceOrder> queryBecomeDueOrders() {
        return payExperienceOrderMapper.queryBecomeDueOrders();
    }

    @Override
    public int countSuccessfulNum(String memberId) {
        if (StringUtils.isNotBlank(memberId)) {
            return payTbillMapper.countSuccessfulNum(memberId);
        }
        return 0;
    }

    @Override
    public int countExperienceSuccessfulNum(String memberId) {
        if (StringUtils.isNotBlank(memberId)) {
            return payExperienceOrderMapper.countSuccessfulNum(memberId);
        }
        return 0;
    }

    private void msgByWaitPay(String memberId) {
        Msg msg = new Msg();
        msg.setMemberId(memberId);
        msg.setType(CommonConstants.MsgType.WAITING_PAY_TBILL.getIndex());
        SerializeObject resultRate = rateSettingsService.get(RateKeyEnum.UNPAID_TIME.getKey());
        if (resultRate.getData() != null) {
            Map<String, Object> resultRateMap = (Map<String, Object>) resultRate.getData();
            Map<String, String> paramMap = new HashMap<>();
            paramMap.put("minutes", String.valueOf(resultRateMap.get(RateKeyEnum.UNPAID_TIME.getKey())));
            msg.setParamMap(paramMap);
        }
        amqpTemplate.convertAndSend(QUEUE_MSG_SEND, msg);
    }

    @Override
    public List<PayTbill> query(String mobile, String name, int startGram, int endGram, String startDate, String endDate, int status, String source, String order, String sort, int offset, int size, Integer[] productType,
                                String tbillNo, String tbillMoneyMin, String tbillMoneyMax) {

        List<String> orders = Arrays.asList("total_gram", "add_time", "total_amount");
        Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(mobile)) {
            params.put("mobile", mobile);
        }
        if (StringUtils.isNotBlank(name)) {
            params.put("name", name);
        }
        if (startGram >= 0) {
            params.put("startGram", startGram);
        }
        if (endGram >= 0) {
            params.put("endGram", endGram);
        }
        if (StringUtils.isNotBlank(startDate)) {
            params.put("startDate", startDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            params.put("endDate", endDate);
        }
        params.put("status", status);
        if (StringUtils.isNotBlank(source)) {
            params.put("source", source);
        }
        if (orders.contains(order)) {
            params.put("order", order);
            params.put("sort", "desc");
            if (StringUtils.equalsIgnoreCase(sort, "asc") || StringUtils.equalsIgnoreCase(sort, "desc")) {
                params.put("sort", sort);
            }
        }

        if (productType != null && productType.length > 0) {
            params.put("productType", productType);
        }

        if (StringUtils.isNotBlank(tbillNo)) {
            params.put("tbillNo", tbillNo);
        }

        if (StringUtils.isNotBlank(tbillMoneyMin)) {
            params.put("tbillMoneyMin", tbillMoneyMin);
        }

        if (StringUtils.isNotBlank(tbillMoneyMax)) {
            params.put("tbillMoneyMax", tbillMoneyMax);
        }

        params.put("offset", offset);
        params.put("size", size);
        return payTbillMapper.query(params);
    }

    @Override
    public int count(String mobile, String name, int startGram, int endGram, String startDate, String endDate, int status, String source, Integer[] productType,
                     String tbillNo, String tbillMoneyMin, String tbillMoneyMax) {
        Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(mobile)) {
            params.put("mobile", mobile);
        }
        if (StringUtils.isNotBlank(name)) {
            params.put("name", name);
        }
        if (startGram >= 0) {
            params.put("startGram", startGram);
        }
        if (endGram >= 0) {
            params.put("endGram", endGram);
        }
        if (StringUtils.isNotBlank(startDate)) {
            params.put("startDate", startDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            params.put("endDate", endDate);
        }
        params.put("status", status);
        if (StringUtils.isNotBlank(source)) {
            params.put("source", source);
        }

        if (productType != null && productType.length > 0) {
            params.put("productType", productType);
        }

        if (StringUtils.isNotBlank(tbillNo)) {
            params.put("tbillNo", tbillNo);
        }

        if (StringUtils.isNotBlank(tbillMoneyMin)) {
            params.put("tbillMoneyMin", tbillMoneyMin);
        }

        if (StringUtils.isNotBlank(tbillMoneyMax)) {
            params.put("tbillMoneyMax", tbillMoneyMax);
        }
        return payTbillMapper.count(params);
    }

    @Override
    public List<FrozenTbillBean> queryForFrozenTbills(String mobile, String name, int startGram, int endGram, String startDate, String endDate, String order, String sort, int offset, int size) {
        List<String> orders = Arrays.asList("totalGram");
        Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(mobile)) {
            params.put("mobile", mobile);
        }
        if (StringUtils.isNotBlank(name)) {
            params.put("name", name);
        }
        if (startGram >= 0) {
            params.put("startGram", startGram);
        }
        if (endGram >= 0) {
            params.put("endGram", endGram);
        }
        if (StringUtils.isNotBlank(startDate)) {
            params.put("startDate", startDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            params.put("endDate", endDate);
        }
        if (orders.contains(order)) {
            params.put("order", order);
            params.put("sort", "desc");
            if (StringUtils.equalsIgnoreCase(sort, "asc") || StringUtils.equalsIgnoreCase(sort, "desc")) {
                params.put("sort", sort);
            }
        }
        params.put("offset", offset);
        params.put("size", size);
        return payTbillMapper.queryForFrozenTbills(params);
    }

    @Override
    public int countForFrozenTbills(String mobile, String name, int startGram, int endGram, String startDate, String endDate) {
        Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(mobile)) {
            params.put("mobile", mobile);
        }
        if (StringUtils.isNotBlank(name)) {
            params.put("name", name);
        }
        if (startGram >= 0) {
            params.put("startGram", startGram);
        }
        if (endGram >= 0) {
            params.put("endGram", endGram);
        }
        if (StringUtils.isNotBlank(startDate)) {
            params.put("startDate", startDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            params.put("endDate", endDate);
        }
        return payTbillMapper.countForFrozenTbills(params);
    }

    @Override
    public int queryCountForRecordsList(String memberId) {
        return payTbillMapper.queryCountForRecordsList(memberId);
    }

    @Override
    public SerializeObject findInvestList(Map map) {
        if (null == map.get("endTime")) {
            return new SerializeObject<>(ResultType.ERROR, "00000002");
        }
        if (null == map.get("redNum")) {
            return new SerializeObject<>(ResultType.ERROR, "00000002");
        }
        List<UserInvestBean> list = payTbillMapper.findInvestList(map);
        if (!CollectionUtils.isEmpty(list)) {
            for (UserInvestBean bean : list) {
                bean.setLoginName(UF.getFormatMobileShowThree(bean.getLoginName()));
            }
        }
        return new SerializeObject<>(ResultType.NORMAL, list);
    }
}